module(..., package.seeall)
--- 模块功能：
-- @author zhangfenghe
-- @module access_control_system.utils
-- @license MIT
-- @copyright openLuat
-- @release 2024.02.26
require "mqtt"
require "misc"
require "nvm"
require "config"
require "audio"
require "displayLogic"
require "mqttHostInMsg"
require "doorLocStatFeedback"
nvm.init("config.lua", true)
TimeIdEmergencyToDisolay = nil
local ttsStr, resultPlayEmergency = "紧急报警,紧急报警,紧急报警",
                                    false
EmerInterruptFlag, QuakeInterruptFlag = false, false
local openTime, alarmTime = nvm.get("OpenTime"), nvm.get("AlarmTime")
-- gpio16:设备静音设置 1-静音，0-非静音，gpio17:应急灯亮灭控制 1-亮，0-灭，gpio19:报警音播报控制 1-播放，0-停止，gpio26:设置开关门初始状态1-关门，0-开门
local setGpio16Fnc, setGpio17Fnc, setGpio19Fnc, setGpio26Fnc = pins.setup(
                                                                   pio.P0_16, 1),
                                                               pins.setup(
                                                                   pio.P0_17, 0),
                                                               pins.setup(
                                                                   pio.P0_19, 0),
                                                               pins.setup(
                                                                   pio.P0_26, 1) -- 设置开关门初始状态1-关门，0-开门
local countrevMsg = 0
local function openLogic()
    setGpio26Fnc(0)
    sys.wait(1000 * openTime)
    setGpio26Fnc(1)
end
-- 设备打开静音
local function muteOpen() setGpio16Fnc(1) end
-- 设备解除静音
local function unmuteOpen() setGpio16Fnc(0) end

-- 应急灯打开
local function emergencyLightOpen() setGpio17Fnc(1) end
-- 应急灯关闭
local function emergencyLightClos() setGpio17Fnc(0) end

-- 报警音播放
local function alarmVideoPlay() setGpio19Fnc(1) end

-- 报警音停止
local function alarmVideoStop() setGpio19Fnc(0) end

-- 紧急开门
local function openDoorActionEmergency() setGpio26Fnc(0) end
-- 紧急关门
local function closDoorActionEmergency() setGpio26Fnc(1) end
-- 执行开门
function OpenDoorAction() sys.taskInit(openLogic) end

-- 执行关门
function ClosDoorAction() setGpio26Fnc(1) end

-- 紧急预警
local function emergencyAlarm()
    ttsStr = "紧急报警,紧急报警,紧急报警"
    if not QuakeInterruptFlag then
        EmerInterruptFlag = true
        -- 开门
        openDoorActionEmergency()
        -- 报警音逻辑
        unmuteOpen()
        emergencyLightOpen()
        if doorLocStatFeedback.OpenDoorDisplay then
            if doorLocStatFeedback.OpenDoorSendMsgTime ~= nil then
                doorLocStatFeedback.OpenDoorSendMsgTime = sys.timerStop(
                                          doorLocStatFeedback.OpenDoorSendMsgTime)
            end
            displayLogic.OpenDisplayCancel()
        end
        if not displayLogic.TimeId then displayLogic.NomalTask() end
        displayLogic.NomalTask()
        TimeIdEmergencyToDisolay = sys.timerLoopStart(
                                       displayLogic.EmergencyAlarmDisplay, 125)

        if EmerInterruptFlag then
            audio.play(4, "TTS", ttsStr, 7,
                       function() sys.publish("PLAY_END") end)
            sys.waitUntil("PLAY_END")
        end
        if EmerInterruptFlag then
            resultPlayEmergency = audio.play(3, "FILE", "/lua/warning.mp3", 7,
                                             function(result)
                log.info("result", result)
            end, true, 0)
        end
    end
end
-- 紧急预警取消
function EmergencyAlarmCancel()
    log.info("Test2")
    if EmerInterruptFlag then
        log.info("resultPlayEmergency", resultPlayEmergency,
                 "timeIdEmergencyToDisolay", TimeIdEmergencyToDisolay)
        EmerInterruptFlag = false
        setGpio26Fnc(1)
        if resultPlayEmergency then audio.stop() end
        if TimeIdEmergencyToDisolay then
            sys.timerStop(TimeIdEmergencyToDisolay)
            TimeIdEmergencyToDisolay = nil
        end
        if not QuakeInterruptFlag then displayLogic.NomalTask() end
    end
end

-- 地震预警取消
local function quakeActionCancel()
    QuakeInterruptFlag = false
    alarmVideoPlay()
    sys.wait(100)
    alarmVideoStop()
    muteOpen()
    emergencyLightClos()
    displayLogic.NomalTask()
end
local function quakeVoiceStart()
    alarmVideoPlay()
    sys.wait(100)
    alarmVideoStop()
end
-- 地震预警音重置
local function quakeVoiceReset()
    log.info("报警音重置")
    alarmVideoPlay()
    sys.wait(100)
    alarmVideoStop()
    sys.wait(100)
    alarmVideoPlay()
    sys.wait(100)
    alarmVideoStop()
end
-- 地震预警取消
local function quakeCancelTask()
    while true do
        log.info("mqttHostInMsg.QuakeCancelFlag", mqttHostInMsg.QuakeCancelFlag)
        if mqttHostInMsg.QuakeCancelFlag then
            quakeActionCancel()
            break
        end
        sys.wait(1000)
    end
end
-- 地震预警
function QuakeAction(r, g, b, count, intense, hz, voice)
    log.info("voice:", voice)
    ttsStr = "地震预警,地震预警,地震预警。"
    local quakeCountDown = tonumber(count)
    if QuakeInterruptFlag == false then
        QuakeInterruptFlag = true
        sys.taskInit(quakeCancelTask)
        if EmerInterruptFlag then
            EmergencyAlarmCancel()
        else
            log.info("正常2")
            displayLogic.NomalTask()
        end
        -- 开门
        log.info("string.sub(voice, 1, 1):", string.sub(voice, 1, 1),
                 string.sub(voice, 1, 1) == "1")
        if string.sub(voice, 1, 1) == "1" then
            log.info("报警音开始")
            openDoorActionEmergency()
            -- 报警音逻辑
            unmuteOpen()
            sys.taskInit(quakeVoiceStart)
            audio.play(4, "TTS", ttsStr, 7)
            emergencyLightOpen()
        end
    end
    countrevMsg = countrevMsg + 1
    if string.sub(voice, 1, 1) == "1" then
        if math.fmod(countrevMsg, 11) == 0 then
            sys.taskInit(quakeVoiceReset)
        end
    end
    if quakeCountDown <= 10 and quakeCountDown > 0 then
        if quakeCountDown == 10 then
            audio.play(4, "TTS", string.sub(count, 2, 3), 7)
        else
            audio.play(4, "TTS", string.sub(count, 3, 3), 7)
        end

    end
    if quakeCountDown > 0 then
        displayLogic.QuakeAlarmDisplay(r, g, b, count, intense, hz)
    elseif quakeCountDown == 0 then
        if math.fmod(countrevMsg, 2) == 0 then
            local data = (string.format("%02x", "0x55") ..
                             string.format("%02x", "0x06") ..
                             string.format("%02x", "0x06") ..
                             string.format("%02x", "0x06") ..
                             string.format("%02x", "0x06") ..
                             string.format("%02x", "0x06") ..
                             string.format("%02x", "0x00") ..
                             string.format("%02x", "0x00") ..
                             string.format("%02x", "0x00") ..
                             string.format("%02x", "0xff")):fromHex()
            uartTask.Write(data)
        else
            displayLogic.QuakeAlarmDisplay(r, g, b, count, intense, hz)
        end
    end

end
-- 紧急预警方式
function EmergencyAlarmLogic() sys.taskInit(emergencyAlarm) end
